const { Node } = require('n8n-core');
const { NodeApiError } = require('n8n-workflow');

class XiheNode extends Node {
    constructor() {
        super();
        this.authToken = null;
    }

    async execute() {
        const items = this.getInputData();
        const returnItems = [];

        for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
            try {
                const operation = this.getNodeParameter('operation', itemIndex) as string;
                const path = this.getNodeParameter('path', itemIndex) as string;
                const params = this.getNodeParameter('params', itemIndex, {}) as Record<string, any>;
                const data = this.getNodeParameter('data', itemIndex, {}) as Record<string, any>;
                const jsonData = this.getNodeParameter('jsonData', itemIndex, {}) as Record<string, any>;
                const needAuth = this.getNodeParameter('needAuth', itemIndex, true) as boolean;

                let response;
                switch (operation) {
                    case 'GET':
                        response = await this.get(path, params, needAuth);
                        break;
                    case 'POST':
                        response = await this.post(path, jsonData, data, needAuth);
                        break;
                    case 'PUT':
                        response = await this.put(path, data, needAuth);
                        break;
                    case 'DELETE':
                        response = await this.delete(path, needAuth);
                        break;
                    case 'LOGIN':
                        response = await this.login(data.username, data.password);
                        break;
                    default:
                        throw new NodeApiError(this.getNode(), { message: `Unsupported operation: ${operation}` });
                }

                returnItems.push({
                    json: response,
                });
            } catch (error) {
                if (this.continueOnFail()) {
                    returnItems.push({ json: { error: error.message } });
                } else {
                    throw error;
                }
            }
        }

        return this.prepareOutputData(returnItems);
    }

    async get(path, params = {}, needAuth = true) {
        const url = this.getUrl(path);
        const headers = needAuth ? this.getAuthHeaders() : {};
        const response = await this.helpers.httpRequest({
            method: 'GET',
            url,
            headers,
            qs: params,
        });
        return response;
    }

    async post(path, jsonData = {}, data = {}, needAuth = true) {
        const url = this.getUrl(path);
        const headers = needAuth ? this.getAuthHeaders() : {};
        const response = await this.helpers.httpRequest({
            method: 'POST',
            url,
            headers,
            body: jsonData,
            qs: data,
        });
        return response;
    }

    async put(path, data = {}, needAuth = true) {
        const url = this.getUrl(path);
        const headers = needAuth ? this.getAuthHeaders() : {};
        const response = await this.helpers.httpRequest({
            method: 'PUT',
            url,
            headers,
            body: data,
        });
        return response;
    }

    async delete(path, needAuth = true) {
        const url = this.getUrl(path);
        const headers = needAuth ? this.getAuthHeaders() : {};
        const response = await this.helpers.httpRequest({
            method: 'DELETE',
            url,
            headers,
        });
        return response;
    }

    async login(username, password) {
        const url = this.getUrl('/cg_job/cgtw/user_login');
        const response = await this.helpers.httpRequest({
            method: 'POST',
            url,
            body: {
                username,
                password,
            },
        });

        if (response.statusCode !== 200) {
            throw new NodeApiError(this.getNode(), { message: `Login error ${response.statusCode}: ${response.statusMessage}` });
        }

        this.authToken = response.body;
        return response.body;
    }

    getUrl(path) {
        const baseUrl = this.getNodeParameter('baseUrl', 0) as string;
        return `${baseUrl}${path}`;
    }

    getAuthHeaders() {
        if (!this.authToken) {
            return {};
        }

        return {
            'user_id': this.authToken.user_id,
            'key': this.authToken.key,
        };
    }

    addAuth(data) {
        if (!data || !this.authToken) {
            return data;
        }

        if (typeof data !== 'object') {
            return {
                user_id: this.authToken.user_id,
                key: this.authToken.key,
            };
        }

        return {
            ...data,
            user_id: this.authToken.user_id,
            key: this.authToken.key,
        };
    }
}

module.exports = XiheNode;